<?php
namespace Admin\Controller;

use Think\Model;

/**
 * 后台JqGrid表格入口实现类
 */
class JqGridController extends GridController {
	/**
	 * 操作主键
	 * @var int|array
	 */
	protected $id;
	/**
	 * 操作类型
	 * @var String
	 */
	protected $oper;
	/**
	 * 更新|编辑的数据
	 * @var array()
	 */
	protected $data;
	/**
	 * 编辑|删除的条件
	 * @var array()
	 */
	protected $condition;
	/**
	 * 是否检查字段
	 * @var boolean
	 */
	protected $auto_check=true;
	/**
	 * 构造函数：填充成员变量
	 */
	public function __construct(){
		$this->oper=I('post.oper',null);
		$id=I('post.id',null);
		$this->data=array();
		if(!is_null($id)){
			if($this->oper=='edit'){
				$this->id=intval($id);
				$this->condition=array('id'=>$this->id);
				$this->data['id']=$this->id;//用于判断为修改数据
			}
			else if($this->oper=='del'){
				$this->id=explode(',',$id);
				if(1==count($this->id)){
					$this->id=intval($id);
					$this->condition=array('id'=>$this->id);
				}else{
					$this->condition=array('id'=>array('in',$this->id));
				}
			}
		}
		parent::__construct();
	}
	
	protected final function set_options(){
		//默认第一页
		$this->options['page']=I('post.page',1,'int');
		//默认显示的记录数
		$this->options['rows']=I('post.rows',DEFAULT_ROWS,'int');
		//排序规则
		$sidx=I('post.sidx','');
		$sord=I('post.sord','');
		if(!empty($sidx)&&!empty($sord)) $this->options['order']=$sidx.' '.$sord;
		$this->search=I('_search',null)=='true'?true:false;
	}
	
	protected final function get_condition(){
		if(!$this->search){
			return array();
		}else{
			$searchField=I('post.searchField',null);
			$searchString=I('post.searchString',null);
			$searchOper=I('post.searchOper',null);
			//多条件查询
			$filters=$_POST['filters'];//原样接收
			//多条件查询
			if(!empty($filters)){
				//条件转化为数组格式
				$multipleSearch=json_decode($filters,true);
				$conditions=$this->multipleSearchArray($multipleSearch);
			}
			//单值查询
			else if($searchOper){
				//获得单个查询的条件
				$conditions=$this->getSearchArray($searchField, $searchString, $searchOper);
			}
			return $conditions;
		}
	}
	/**
	 * 修改时间戳为日期格式
	 * @param string $field
	 * @return string 
	 */
	private function fromUnixTime(&$field){
		$field='FROM_UNIXTIME(dateline,"%Y-%m-%d")';
		return $field;
	}
	/**
	 * 判断是否为时间戳格式
	 * @param string $field
	 * @return boolean 
	 */
	private function isUnixTimeField(&$field){
		if($field=='dateline'){
			return true;
		}
		return false;
	}
	
	/**
	 * 获得查找条件，数组格式
	 * @param string $searchField 查询域名
	 * @param string $searchString 查询条件
	 * @param string $searchOper 查询操作
	 * @return array 查询条件
	 */
	private function getSearchArray($searchField,$searchString,$searchOper){
		if($this->isUnixTimeField($searchField)){
			$searchOption['_string']=$this->getSearchString($searchField, $searchString, $searchOper);
			return $searchOption;
		}
	
		//定义的一些匹配规则
		$sopt=array('eq'=>'EQ','ne'=>'NEQ','lt'=>'LT','le'=>'ELT','gt'=>'GT','ge'=>'EGT','bw'=>'LIKE','bn'=>'NOT LIKE',
				'in'=>'IN','ni'=>'NOT IN','ew'=>'LIKE','en'=>'NOT LIKE','cn'=>'LIKE','nc'=>'NOT LIKE',
				'nu'=>'IS NULL','nn'=>'IS NOT NULL');
		//开始于与不开始于
		if (in_array($searchOper, array('bw','bn'))){
			$searchString.='%';
		}
		//属于与不属于
		else if (in_array($searchOper, array('in','ni'))){
			$searchString=split(',',$searchString);
		}
		//结束于与不结束于
		else if(in_array($searchOper, array('ew','en'))){
			$searchString='%'.$searchString;
		}
		//包含与不包含
		else if(in_array($searchOper, array('cn','nc'))){
			$searchString="%$searchString%";
		}
		//为空或不为空
		if(in_array($searchOper, array('nu','nn'))){
			$searchOption[$searchField]=array('EXP',$sopt[$searchOper]);
		}
		else{
			$searchOption[$searchField]=array($sopt[$searchOper],$searchString);
		}
		return $searchOption;
	}
	
	/**
	 * 获得查找条件，字符串格式
	 * @param string $searchField 查询域名
	 * @param string $searchString 查询条件
	 * @param string $searchOper 查询操作
	 * @return string 查询条件
	 */
	private function getSearchString($searchField,$searchString,$searchOper){
		//定义的一些匹配规则
		$sopt=array('eq'=>'=','ne'=>'<>','lt'=>'<','le'=>'<=','gt'=>'>','ge'=>'>=','bw'=>'like','bn'=>'not like',
				'in'=>'in','ni'=>'not in','ew'=>'like','en'=>'not like','cn'=>'like','nc'=>'not like',
				'nu'=>'is null','nn'=>'is not null');
	
		if($this->isUnixTimeField($searchField)){
			$this->fromUnixTime($searchField);
		}
	
		//开始于与不开始于
		if (in_array($searchOper, array('bw','bn'))){
			$searchString.='%';
		}
		//属于与不属于
		else if (in_array($searchOper, array('in','ni'))){
			$searchString=split(',',$searchString);
			foreach ($searchString as $i=>$s){
				$searchString[$i]="`'$s'`";//给每个条件项加引号
			}
			$searchString='('.explode(',',$searchString).')';
		}
		//结束于与不结束于
		else if(in_array($searchOper, array('ew','en'))){
			$searchString='%'.$searchString;
		}
		//包含与不包含
		else if(in_array($searchOper, array('cn','nc'))){
			$searchString="%$searchString%";
		}
		if(!in_array($searchOper, array('in','ni'))){
			$searchString="'$searchString'";
		}
		//获得正确sql
		return "$searchField $sopt[$searchOper] $searchString";
	}
	/**
	 * 获得多值查询的查询条件
	 * @param array $multipleSearch 符合查询条件，参考 <a href="http://www.trirand.net/demophp.aspx">http://www.trirand.net/demophp.aspx</a>
	 * @return array 符合thinkphp的规则的查询数组
	 */
	private function multipleSearchArray($multipleSearch){
		$conditions=array();
		foreach ($multipleSearch['rules'] as $rule){
			//获得搜索条件数组
			$searchArray=$this->getSearchArray($rule['field'],$rule['data'],$rule['op']);
			if(array_key_exists($rule['field'],$conditions)){
				$conditions[$rule['field']]=array_merge($conditions[$rule['field']],$searchArray[$rule['field']]);
			}else{
				$conditions=array_merge($conditions,$searchArray);
			}
		}
		/*--------------------------------------------------------------------
		--- 由于thinkphp自带的_complex存在缺陷，只能用string类型---------------
		--------------------------------------------------------------------*/
		if(!empty($multipleSearch['groups'])){
			$conditions['_string']=$this->multipleSearchString($multipleSearch['groups'],$multipleSearch['groupOp']);
		}
		//分组逻辑操作符
		$conditions['_logic']=$multipleSearch['groupOp'];
		return $conditions;
	}
	/**
	 * 获得查询string
	 * @param array $groups 操作组
	 * @param string 操作
	 */
	private function multipleSearchString($groups,$op){
		$searchOption=array();
		foreach ($groups as $group){
			if(!empty($group['groups'])){
				$searchOption[]='('.$this->multipleSearchString($group['groups'],$group['groupOp']).')';
			}
			if(!empty($group['rules'])){
				$searchRules=array();
				foreach ($group['rules'] as $rule){
					$searchField=$rule['field'];
					$searchString=$rule['data'];
					$searchOper=$rule['op'];
					$searchRules[]=$this->getSearchString($searchField, $searchString, $searchOper);
				}
				$searchOption[]='('.join(' '.$group['groupOp'].' ', $searchRules).')';
			}
		}
		return join(' '.$op.' ', $searchOption);
	}
	
	/**
	 * 支持jqgrid的filterToolbar的查询功能
	 * @param array $options 查询配置
	 * @param array $request 前台请求数组
	 * @return array 查询条件
	 */
	protected function filterToolbar($options,$request){
		$where=array();
		foreach($options as $option){
			$field=$option['field'];
			if(!isset($request[$field])){
				continue;
			}
			$value=$request[$field];
			$op=$option['op'];
			if(isset($value)){
				if(isset($option['ignore'])&&$option['ignore']==$value){
					continue;
				}
				if($this->isUnixTimeField($field)){
					$where['_string']=$this->getSearchString($field, $value, $op);
					continue;
				}
				if($op=='eq'){
					$where[$field]=$value;
				}else if($op=='like'){
					$where[$field]=array('LIKE','%'.$value.'%');
				}else if($op=='ge'){
					$where[$field]=array('EGT',$value);
				}else if($op=='nu'){
					if($value=='nu') $where[$field]=array('EXP','IS NULL');
					else if($value=='nn') $where[$field]=array('EXP','IS NOT NULL');
				}
				else continue;
			}
		}
		return $where;
	}
	/**
	 * 默认的filterToolbar的查询，默认全部使用模糊查询（LIKE）
	 * @param array $fields 查询域名数组
	 * @param array $request 前台请求数组
	 * @return array 查询条件
	 */
	protected function defaultFilterToolbar($fields,$request){
		$options=array();
		foreach ($fields as $field){
			$options[]=array('field'=>$field,'op'=>'like');
		}
		return $this->filterToolbar($options,$request);
	}
	
	protected function select($options=array()){
		$result=parent::select($options);
		if(!$result){
			return null;
		}else{
			$json['rows']=$result['result'];
			$json['page']=$result['page'];
			$json['total']=$result['pages'];
			$json['records']=$result['counts'];
		}
		if(isset($options['retJson'])&&false===$options['retJson']){
			return $json;
		}else{
			return $this->ajaxReturn($json);
		}
	}
	/**
	 * 增删改操作公共入口函数
	 * @param array $callbacks 回调函数
	 */
	protected function oper($callbacks=array()){
		if(!$this->dao){
			$this->error(L('NO_POWER'));
			return false;
		}
		//如果不判断删除则会验证
		if($this->auto_check&&$this->oper!='del'){
			if(!$this->dao->create($this->data,Model::MODEL_INSERT)){
				$this->error($this->dao->getError());
				return false;
			}
		}
		$callback=array();
		if(isset($callbacks['success'])){
			$callback=$callbacks['success'];
		}
		if(isset($callbacks[$this->oper.'_success'])){
			$callback=$callbacks[$this->oper.'_success'];
		}
		switch ($this->oper){
			case "edit":{
				if($this->edit($this->condition, $this->data)){
					$this->callback($callback);
					$this->success(L('UPDATE_SUCCESS'));
					return true;
				}else{
					$this->error(L('UPDATE_FAILURE'));
					return false;
				}
			}
			case "del":{
				if($this->delete($this->condition)){
					$this->callback($callback);
					$this->success(L('DELETE_SUCCESS'));
					return true;
				}else{
					$this->error(L('DELETE_FAILURE'));
					return false;
				}
			}
			case "add":{
				if($this->add($this->data)){
					$this->callback($callback);
					$this->success(L('POST_SUCCESS'));
					return true;
				}else{
					$this->error(L('POST_FAILURE'));
					return false;
				}
			}
			default:
				$this->error(L('NO_POWER'));
				return false;
		}
	}
	
	/**
	 * 操作回调函数
	 * @param array $callback
	 */
	private function callback($callback){
		if(!empty($callback['function'])){
			call_user_func($callback['function'],$callback['params']);
		}
	}
	
	/**
	 * 通用表格模块显示
	 */
	protected function _grid_display($layout='default'){
		layout(false);
		//输出各个操作的权限字符串
		$this->_operation_power();
		$this->assign('pager',$this->_item());
		$Lang=array('CAPTION'=>L(ACTION_NAME.'_CAPTION'),'TIP'=>L(ACTION_NAME.'_TIP'),'COL_NAMES'=>L(ACTION_NAME.'_COL_NAMES'));
		$this->assign('Lang',$Lang);
		$this->assign('layout',$layout);
		$this->display();
	}
}